{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 多层感知机的简洁实现",
   "id": "b44b56702150787e"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-08-12T08:44:27.485277Z",
     "start_time": "2025-08-12T08:44:27.482279Z"
    }
   },
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "from d2l import torch as d2l\n",
    "from utils_09 import *"
   ],
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-12T08:44:27.533058Z",
     "start_time": "2025-08-12T08:44:27.494054Z"
    }
   },
   "cell_type": "code",
   "source": [
    "batch_size = 256\n",
    "\n",
    "train_iter,test_iter = load_data_fashion_mnist(batch_size=256,cpu_workers=5)"
   ],
   "id": "b9689a5d34e56684",
   "outputs": [],
   "execution_count": 7
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-12T08:44:27.544195Z",
     "start_time": "2025-08-12T08:44:27.539824Z"
    }
   },
   "cell_type": "code",
   "source": [
    "net = nn.Sequential(\n",
    "    nn.Flatten(),\n",
    "    nn.Linear(784,256),\n",
    "    nn.ReLU(),\n",
    "    nn.Linear(256,10)\n",
    ")"
   ],
   "id": "3ca8c5fbf6fdfb45",
   "outputs": [],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-12T08:44:27.558278Z",
     "start_time": "2025-08-12T08:44:27.553275Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def init_weights(layers:nn.Module):\n",
    "    if isinstance(layers,nn.Linear):\n",
    "        nn.init.normal_(layers.weight,std = 0.01)\n",
    "net.apply(init_weights)"
   ],
   "id": "a3ec71b86cf6239e",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Sequential(\n",
       "  (0): Flatten(start_dim=1, end_dim=-1)\n",
       "  (1): Linear(in_features=784, out_features=256, bias=True)\n",
       "  (2): ReLU()\n",
       "  (3): Linear(in_features=256, out_features=10, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-12T08:44:27.571951Z",
     "start_time": "2025-08-12T08:44:27.568748Z"
    }
   },
   "cell_type": "code",
   "source": [
    "lr = 0.1\n",
    "num_epochs = 50\n",
    "loss = nn.CrossEntropyLoss()\n",
    "trainer = torch.optim.SGD(net.parameters(),lr=lr)"
   ],
   "id": "2edada185661bd25",
   "outputs": [],
   "execution_count": 10
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-08-12T08:51:52.734732Z",
     "start_time": "2025-08-12T08:44:27.585459Z"
    }
   },
   "cell_type": "code",
   "source": [
    "metric = Accumulator(3)\n",
    "train_loss_record = list()\n",
    "train_acc_record = list()\n",
    "test_acc_record = list()\n",
    "for epoch in range(num_epochs):\n",
    "    for X,y in train_iter:\n",
    "        y_predict = net(X)\n",
    "        l = loss(y_predict,y)\n",
    "        trainer.zero_grad()\n",
    "        l.mean().backward()\n",
    "        trainer.step()\n",
    "        metric.add(float(l.sum()),accuracy(y_predict,y),y.numel())\n",
    "    train_metric = (metric[0]/metric[2],metric[1]/metric[2])\n",
    "    test_acc = evaluate_accuracy(net,test_iter)\n",
    "    print(f\"epoch {epoch}, train loss : {train_metric[0]}, train acc : {train_metric[1]},test_acc : {test_acc}\")\n",
    "    train_loss_record.append(train_metric[0])\n",
    "    train_acc_record.append(train_metric[1])\n",
    "    test_acc_record.append(test_acc)\n",
    "train_loss, train_acc = train_metric ## 训练结束，输出训练指标"
   ],
   "id": "a0d9ec6c28f7e878",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 0, train loss : 0.004084536186854045, train acc : 0.6459,test_acc : 0.7601333333333333\n",
      "epoch 1, train loss : 0.0032140098539491496, train acc : 0.7181416666666667,test_acc : 0.8199833333333333\n",
      "epoch 2, train loss : 0.0028189289137721062, train acc : 0.7512888888888889,test_acc : 0.7957\n",
      "epoch 3, train loss : 0.0025819231724987426, train acc : 0.7714458333333334,test_acc : 0.8435666666666667\n",
      "epoch 4, train loss : 0.002421068326930205, train acc : 0.7850666666666667,test_acc : 0.8226833333333333\n",
      "epoch 5, train loss : 0.0022998881160385077, train acc : 0.7952833333333333,test_acc : 0.8410833333333333\n",
      "epoch 6, train loss : 0.0022041689145423115, train acc : 0.8036714285714286,test_acc : 0.8494333333333334\n",
      "epoch 7, train loss : 0.0021245000769073764, train acc : 0.8105458333333333,test_acc : 0.8454666666666667\n",
      "epoch 8, train loss : 0.002058587093927242, train acc : 0.8161944444444444,test_acc : 0.8651666666666666\n",
      "epoch 9, train loss : 0.0020014106865723926, train acc : 0.82116,test_acc : 0.8528666666666667\n",
      "epoch 10, train loss : 0.0019514578346275923, train acc : 0.8254030303030303,test_acc : 0.8663\n",
      "epoch 11, train loss : 0.0019074074033026895, train acc : 0.8291944444444445,test_acc : 0.8392333333333334\n",
      "epoch 12, train loss : 0.001867532623024323, train acc : 0.8326282051282051,test_acc : 0.8739166666666667\n",
      "epoch 13, train loss : 0.00183168937230394, train acc : 0.8357321428571428,test_acc : 0.8679333333333333\n",
      "epoch 14, train loss : 0.0017992522003584437, train acc : 0.8385,test_acc : 0.8787\n",
      "epoch 15, train loss : 0.0017697568033821882, train acc : 0.8410270833333333,test_acc : 0.8781666666666667\n",
      "epoch 16, train loss : 0.0017418189422903107, train acc : 0.8433911764705883,test_acc : 0.86255\n",
      "epoch 17, train loss : 0.0017164889307485687, train acc : 0.8455768518518518,test_acc : 0.8818333333333334\n",
      "epoch 18, train loss : 0.0016923593476806816, train acc : 0.8476070175438597,test_acc : 0.8767166666666667\n",
      "epoch 19, train loss : 0.001669967294918994, train acc : 0.8495358333333334,test_acc : 0.88895\n",
      "epoch 20, train loss : 0.0016489752502786734, train acc : 0.8513222222222222,test_acc : 0.8844666666666666\n",
      "epoch 21, train loss : 0.0016287024762707226, train acc : 0.8530939393939394,test_acc : 0.8869166666666667\n",
      "epoch 22, train loss : 0.001610114071064669, train acc : 0.8546623188405797,test_acc : 0.8870833333333333\n",
      "epoch 23, train loss : 0.0015922699505773684, train acc : 0.8562104166666666,test_acc : 0.8932666666666667\n",
      "epoch 24, train loss : 0.0015751442271272342, train acc : 0.8576966666666667,test_acc : 0.8757833333333334\n",
      "epoch 25, train loss : 0.001558835420404107, train acc : 0.8591185897435898,test_acc : 0.8954833333333333\n",
      "epoch 26, train loss : 0.0015431751335568634, train acc : 0.860491975308642,test_acc : 0.89655\n",
      "epoch 27, train loss : 0.0015283777942880989, train acc : 0.8617767857142857,test_acc : 0.8952333333333333\n",
      "epoch 28, train loss : 0.0015141232324657084, train acc : 0.8630155172413793,test_acc : 0.8984666666666666\n",
      "epoch 29, train loss : 0.0015003084616694185, train acc : 0.86423,test_acc : 0.8961833333333333\n",
      "epoch 30, train loss : 0.0014869535010348083, train acc : 0.8653623655913979,test_acc : 0.8841166666666667\n",
      "epoch 31, train loss : 0.0014741111384549488, train acc : 0.8665026041666667,test_acc : 0.9000833333333333\n",
      "epoch 32, train loss : 0.0014616858026897065, train acc : 0.8675909090909091,test_acc : 0.9041166666666667\n",
      "epoch 33, train loss : 0.0014495569892592874, train acc : 0.8686617647058823,test_acc : 0.9000166666666667\n",
      "epoch 34, train loss : 0.0014379009152381192, train acc : 0.8696704761904762,test_acc : 0.9034666666666666\n",
      "epoch 35, train loss : 0.0014265673433120052, train acc : 0.8706393518518518,test_acc : 0.89905\n",
      "epoch 36, train loss : 0.0014154327044146018, train acc : 0.8716220720720721,test_acc : 0.9001333333333333\n",
      "epoch 37, train loss : 0.0014049620923700563, train acc : 0.8725684210526315,test_acc : 0.9063166666666667\n",
      "epoch 38, train loss : 0.0013946086417023953, train acc : 0.8734807692307692,test_acc : 0.9060666666666667\n",
      "epoch 39, train loss : 0.001384531259847184, train acc : 0.87436625,test_acc : 0.9115\n",
      "epoch 40, train loss : 0.001374792322207515, train acc : 0.8752239837398375,test_acc : 0.8954\n",
      "epoch 41, train loss : 0.0013651584391674353, train acc : 0.8760869047619048,test_acc : 0.90735\n",
      "epoch 42, train loss : 0.0013557916579262693, train acc : 0.8769124031007752,test_acc : 0.9148\n",
      "epoch 43, train loss : 0.0013467285170078729, train acc : 0.8777018939393939,test_acc : 0.9127666666666666\n",
      "epoch 44, train loss : 0.0013378837837168464, train acc : 0.8785096296296296,test_acc : 0.91555\n",
      "epoch 45, train loss : 0.001329244122762179, train acc : 0.8792985507246377,test_acc : 0.8893166666666666\n",
      "epoch 46, train loss : 0.0013209391475305066, train acc : 0.8800471631205674,test_acc : 0.9176833333333333\n",
      "epoch 47, train loss : 0.001312672423162601, train acc : 0.8807777777777778,test_acc : 0.9108\n",
      "epoch 48, train loss : 0.0013044751984884544, train acc : 0.8815336734693877,test_acc : 0.9051333333333333\n",
      "epoch 49, train loss : 0.0012968185117493074, train acc : 0.8822263333333333,test_acc : 0.9126833333333333\n"
     ]
    }
   ],
   "execution_count": 11
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
